package hist.mobilprogramming.tictactoeapplication;

import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


public class MatrixTests
{
	Matrix _matrix;
	Matrix _winMatrix;
	 /* Sets up the test fixture. 
     * (Called before every test case method.) 
     */ 
    @Before 
    public void setUp() 
    { 
    	_winMatrix = new Matrix(5);
    } 

    /* Tears down the test fixture. 
     * (Called after every test case method.) 
     */ 
    @After 
    public void tearDown() 
    { 
         _matrix = null;
         _winMatrix = null;
    } 

    @Test
	public void getElement_WhenZeroDimensionalMatrix_ReturnNull()
	{    	       	
    	_matrix = new Matrix(0);
		int someRandomPositionGreaterThanZero = 1;

		SquareElement result = _matrix.getElement(someRandomPositionGreaterThanZero);
		
		assertEquals(null, result);
	}

    @Test
	public void getElement_WhenDimensionForMatrixIsLessThanZero_ReturnNull()
	{    	       	
    	_matrix = new Matrix(-1);
		int someRandomPositionGreaterThanZero = 1;

		SquareElement result = _matrix.getElement(someRandomPositionGreaterThanZero);
		
		assertEquals(null, result);
	}
    
    @Test
	public void getElement_WhenOneDimensionalMatrix_ReturnElement()
	{    	       	
    	_matrix = new Matrix(1);
    	SquareElement expected = new SquareElement(1, 1);
    	int onlyValidPositionForGivenDimension = 1;

		SquareElement result = _matrix.getElement(onlyValidPositionForGivenDimension);
		
		assertTrue(expected.equals(result));
	}
    
    @Test
	public void getElement_WhenSerialPositionExceedValidRangeForMatrix_ReturnNull()
	{    	       	
    	_matrix = new Matrix(1);
    	int invalidPositionForGivenDimension = 2;

		SquareElement result = _matrix.getElement(invalidPositionForGivenDimension);
		
		assertEquals(null, result);
	}
    
    @Test
	public void getElement_WhenSerialPositionIsUpperBoundForTwoDimensionalMatrix_ReturnElement()
	{    	       	
    	_matrix = new Matrix(2);
    	SquareElement expected = new SquareElement(2, 2);
    	int upperBoundPosition = 4;

		SquareElement result = _matrix.getElement(upperBoundPosition);
		
		assertTrue(expected.equals(result));
	}

    @Test
	public void getElement_WhenSerialPositionInBetweenForTwoDimensionalMatrix_ReturnElement()
	{    	       	
    	_matrix = new Matrix(2);
    	SquareElement expected = new SquareElement(2, 1);
    	int inBetweenPosition = 3;

		SquareElement result = _matrix.getElement(inBetweenPosition);
		
		assertTrue(expected.equals(result));
	}

    @Test
	public void getElement_WhenSerialPositionInBetweenForFiveDimensionalMatrix_ReturnElement()
	{    	       	
    	_matrix = new Matrix(5);
    	SquareElement expected = new SquareElement(3, 3);
    	int inBetweenPosition = 13;

		SquareElement result = _matrix.getElement(inBetweenPosition);
		
		assertTrue(expected.equals(result));
	}
    
    @Test
	public void getElement_WhenSerialPositionIsUpperBoundForNoneSquaredMatrix_ReturnElement()
	{    	       	
    	_matrix = new Matrix(3, 2);
    	SquareElement expected = new SquareElement(3, 2);
    	int upperBoundPosition = 6;

		SquareElement result = _matrix.getElement(upperBoundPosition);
		
		assertTrue(expected.equals(result));
	}

    @Test
	public void getElement_WhenSerialPositionInBetweenForNoneSquaredMatrix_ReturnElement()
	{    	       	
    	_matrix = new Matrix(3,2);
    	SquareElement expected = new SquareElement(3, 1);
    	int inBetweenPosition = 5;

		SquareElement result = _matrix.getElement(inBetweenPosition);
		
		assertTrue(expected.equals(result));
	}
    // Test: pos as 5 when dim=2
    
	@Test
	public void getSerialPositions_IsEmpty_ReturnArrayLengthZero()
	{
    	String[] winnerList = null;
    	
		Integer[] result = _winMatrix.getSerialPositions(winnerList);

		assertArrayEquals(new Integer[0], result);
	}

	@Test
	public void getSerialPositions_HasOneInvalidElement_ReturnMinusOneInPositionArray()
	{
		Integer[] expected = {-1};
    	String[] winnerList = {","};
    	
		Integer[] result = _winMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}

	@Test
	public void getSerialPositions_HasNoneNumerics_ReturnMinusOneInPositionArray()
	{
		Integer[] expected = {-1};
    	String[] winnerList = {"a,b"};
    	
		Integer[] result = _winMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}
	
	@Test
	public void getSerialPositions_HasOneElement_ReturnPositionArray()
	{
		Integer[] expected = {1};
    	String[] winnerList = {"1,1"};
    	
		Integer[] result = _winMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}

	@Test
	public void getSerialPositions_HasTwoElements_ReturnPositionArray()
	{
		Integer[] expected = {1, 2};
    	String[] winnerList = {"1,1", "1,2"};
    	
		Integer[] result = _winMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}

	@Test
	public void getSerialPositions_HasRowOutOfRange_ReturnMinusOneInPositionArray()
	{
		Integer[] expected = {-1};
    	String rowValueOutOfRange = "10";
		String[] winnerList = {rowValueOutOfRange + ",1"};
    	
		Integer[] result = _winMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}

	@Test
	public void getSerialPositions_HasRowLessThanOne_ReturnMinusOneInPositionArray()
	{
		Integer[] expected = {-1};
    	String rowValueToSmall = "0";
		String[] winnerList = {rowValueToSmall + ",1"};
    	
		Integer[] result = _winMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}
	
	@Test
	public void getSerialPositions_HasOneColumnOutOfRange_ReturnMinusOneInPositionArray()
	{
		Integer[] expected = {-1};
    	String colValueOutOfRange = "6";
		String[] winnerList = {"1," + colValueOutOfRange};
    	
		Integer[] result = _winMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}

	@Test
	public void getSerialPositions_HasOneColumnLessThanOne_ReturnMinusOneInPositionArray()
	{
		Integer[] expected = {-1};
    	String colValueToSmall = "0";
		String[] winnerList = {"1," + colValueToSmall};
    	
		Integer[] result = _winMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}
	
	@Test
	public void getSerialPositions_WhenHavingRectangularMatrixWhereThreeElementsToLookFor_ReturnPositionArray()
	{		
		Integer[] expected = {4, 8, 12};
    	String[] winnerList = {"2,1", "3,2", "4,3"};
    	Matrix recMatrix = new Matrix(4, 3);
    	
		Integer[] result = recMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}

	@Test
	public void getSerialPositions_WhenHavingRectangularMatrixWhereFirstPostionShouldBeZero_ReturnPositionArray()
	{		
		Integer[] expected = {0, 4, 8};
    	String[] winnerList = {"1,1", "2,2", "3,3"};
    	Matrix recMatrix = new Matrix(4, 3);
    	recMatrix.changeSerialStartPosition();
    	
		Integer[] result = recMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}
	
	@Test
	public void getSerialPositions_HavingRectangularMatrixWhereFirstPostionShouldBeZeroWhereIncreasingElements_ReturnPositionArray()
	{		
		Integer[] expected = {0, 4, 8};
    	String[] winnerList = {"0,0", "1,1", "2,2"};
    	Matrix recMatrix = new Matrix(4, 3);
    	recMatrix.changeSerialStartPosition();
    	recMatrix.increaseElements();
    	
		Integer[] result = recMatrix.getSerialPositions(winnerList);

		assertArrayEquals(expected, result);
	}
}

